/**
 * Copyright 2009 Adam Ruggles.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.sapien.model;

import java.io.Serializable;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Version;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

import com.google.code.sapien.security.RolePermissions;

/**
 * Role entity data model.  A role is a way to assign permissions to a user.
 * @author Adam
 * @version $Id: Role.java 30 2010-01-10 19:05:55Z a.ruggles $
 * 
 * Created on Mar 6, 2009 at 7:59:22 PM 
 */
@javax.persistence.Entity @Table(name = "sapien_roles")
@NamedQueries({
	@NamedQuery(name = "role.listAll", query = "FROM com.google.code.sapien.model.Role"),
	@NamedQuery(name = "role.getCount", query = "SELECT COUNT(r) FROM com.google.code.sapien.model.Role r"),
	@NamedQuery(name = "role.listForNewUsers",
			query = "FROM com.google.code.sapien.model.Role r WHERE r.userDefault = true")
})
public class Role implements Serializable {
	/**
	 * Serial Version UID. 
	 */
	private static final long serialVersionUID = 6521192034145727653L;

	/**
	 * A flag for determining whether this role is an administrator role.
	 */
	private Boolean administrator;

	/**
	 * The description of the role.
	 */
	private String description;

	/**
	 * A flag for determining whether this role is assigned to all guests when browsing the site.
	 */
	private Boolean guestDefault;

	/**
	 * Unique identifier.
	 */
	private Long id;

	/**
	 * The unique name for the role.
	 */
	private String name;

	/**
	 * A flag for determining whether this role is assigned to new user accounts.
	 */
	private Boolean userDefault;

    /**
     * The version for optimistic concurrency control.
     */
    private Integer version;

	/**
     * Default constructor.
     */
    public Role() {
    	super();
    	this.userDefault = false;
    	this.guestDefault = false;
    }

	/**
     * Constructs a role with a name and description.
     * @param name The name for the new role.
     * @param description The description for the new role.
     */
    public Role(final String name, final String description) {
    	super();
    	this.name = name;
    	this.description = description;
    	this.userDefault = false;
    	this.guestDefault = false;
    }

    /**
	 * {@inheritDoc}
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (!(obj instanceof Role)) {
			return false;
		}
		final Role rhs = (Role) obj;
		return new EqualsBuilder()
			.append(name, rhs.getName())
			.append(description, rhs.getDescription())
			.isEquals();
	}

    /**
	 * Returns administrator.
	 * @return the administrator.
	 */
	public Boolean getAdministrator() {
		return administrator;
	}

	/**
	 * Returns description.
	 * @return the description.
	 */
    @Lob
	public String getDescription() {
		return description;
	}

	/**
	 * Returns guestDefault.
	 * @return the guestDefault.
	 */
	@Basic(optional = false)
	public Boolean getGuestDefault() {
		return guestDefault;
	}

	/**
	 * Returns id.
	 * @return the id.
	 */
	@Id @GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return id;
	}

	/**
	 * Returns name.
	 * @return the name.
	 */
	@Column(length = 25, unique = true, nullable = false)
	public String getName() {
		return name;
	}

	/**
	 * Returns guestDefault.
	 * @return the guestDefault.
	 */
	@Basic(optional = false)
	public Boolean getUserDefault() {
		return userDefault;
	}

	/**
	 * Returns version.
	 * @return the version.
	 */
	@Version
	public Integer getVersion() {
		return version;
	}

	/**
	 * {@inheritDoc}
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return new HashCodeBuilder(3, 37)
			.append(name)
			.append(description)
			.toHashCode();
	}

	/**
	 * Sets administrator.
	 * @param administrator the administrator to set.
	 */
	public void setAdministrator(final Boolean administrator) {
		this.administrator = administrator;
	}

	/**
	 * Sets description.
	 * @param description the description to set.
	 */
	public void setDescription(final String description) {
		this.description = description;
	}

	/**
	 * Sets guestDefault.
	 * @param guestDefault the guestDefault to set.
	 */
	public void setGuestDefault(final Boolean guestDefault) {
		this.guestDefault = guestDefault;
	}

	/**
	 * Sets id.
	 * @param id the id to set.
	 */
	public void setId(final Long id) {
		this.id = id;
	}

	/**
	 * Sets name.
	 * @param name the name to set.
	 */
	public void setName(final String name) {
		this.name = name;
	}

	/**
	 * Sets userDefault.
	 * @param userDefault the userDefault to set.
	 */
	public void setUserDefault(final Boolean userDefault) {
		this.userDefault = userDefault;
	}

	/**
	 * Sets version.
	 * @param version the version to set.
	 */
	public void setVersion(final Integer version) {
		this.version = version;
	}

	/**
	 * Returns a JSON object representing this object in JavaScript.
	 * @return A String.
	 */
	public String toJSON() {
		return new StringBuilder("{")
			.append("id:").append(id)
			.append(",name:'").append(StringEscapeUtils.escapeJavaScript(name))
			.append("',description:'").append(StringEscapeUtils.escapeJavaScript(description))
			.append("',guestDefault:").append(guestDefault)
			.append(",userDefault:").append(userDefault)
			.append(",version:").append(version)
			.append('}').toString();
	}

	/**
	 * {@inheritDoc}
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return new ToStringBuilder(this)
			.append("id", id)
			.append("name", name)
			.append("description", description)
			.append("guestDefault", guestDefault)
			.append("userDefault", userDefault)
			.append("version", version)
			.toString();
	}
}
